package development.game;

import state.GameAlert;
import state.GameConstants;
import state.GameForm;
import state.GameGlobal;
import state.GameImage;
import state.Graphics;
import state.Key;
import state.TimerListener;
import state.font.FontManager;
import state.font.ImageText;
import state.socket.DataPackage;
import state.socket.DataReceiveListener;
import state.util.GameColor;
import state.util.Hashtable;
import state.util.ImageUtil;
import state.util.NumberUtil;
import state.util.TwoDimensionInt;
import state.util.array.IntArray;
import state.util.array.StringArray;
import development.Constants;
import development.DrawUtils;
import development.Global;
import development.bean.BroadChessMan;
import development.bean.ChessMan;
import development.bean.Game;
import development.group.FrmGroupListTableFreeUserChat;
import development.group.FrmGroupTableFreeUserFriend;
import development.socket.SocketClientUtil;

public class FrmBroadChess extends GameForm implements TimerListener, DataReceiveListener {
  private final int MOVE_REQUEST = 1001; // Gửi thông tin về nước đã đi
  private final int WIN_GAME_NOTIFY_RESPONSE = 2006; // Báo cho các user về user đã thắng và danh sách các nước đi thắng
  private final int INIT_DATA_RESPONSE = 2007; // Thiết đặt các thông số cho client
  private final int MOVE_ERROR_RESPONSE = 2008; // Báo lại cho ng chơi vừa đánh là nước đánh không được chấp nhận
  private final int MOVE_NOTIFY_RESPONSE = 2009; // Báo nước đi của người vừa đánh

  private final int NOT_YOUR_TURN_ERROR = 3001;
  private final int MOVE_IN_NOT_ALLOW_POSITION = 3002;

  private final int NORMAL_WIN_REASON = 4001;
  private final int OPPONENT_RESIGN_WIN_REASON = 4002;
  private final int OPPONENT_TIMEOUT_WIN_REASON = 4003;
  
  public static int BOARD_DX;
  public static int BOARD_DY;
  public static int CELL_SIZE;

  private final int NUMBER_OF_ROW = 8;
  private final int NUMBER_OF_COLUMN = 8;
  private int TIME_PER_MOVE;

  private final int WAIT_FOR_INIT_STATUS = 0;
  private final int PLAY_STATUS = 1;
  private final int SHOW_WIN_OR_LOST_ALERT_STATUS = 3;
  private final int SHOW_FINAL_RESULL = 4;

  private GameImage areaImage;
  private GameImage lastMoveSmallImage;
  private GameImage lastMoveLargeImage;
  private GameImage chessBoardImage;
  private GameImage numberBgImage;
  private GameImage matnaImage;
  private GameImage starImage;
  private GameImage thangImage;
  private GameImage thuaImage;

  private BroadChessMan[][] chessMans;
  private BroadChessMan currentSelectArea;
  private BroadChessMan currentSelectArea1;
  private BroadChessMan selectedChessMan;
  private BroadChessMan lastMoveSmallSprite;
  private BroadChessMan lastMoveLargeSprite;

  private ImageText text11;
  private ImageText text8;

  private int mySide;
  private int opponentSide;
  private int currentTurn;
  private int chessManIndex;
  private int currentGameStatus;

  private int winSide;
  private int winReason;
  private String[] moneyChangePoint = new String[2];

  private int[] timePlay = new int[2];
  private int timeMove;
  private int count;
  private String oponentName;
  private String moneyChangeMessage = "";
  private int moneyChangeIndex;
  
  private static GameForm singleton;
  
  public static GameForm instance() {
    if (singleton == null) {
      singleton = new FrmBroadChess();
    }
    return singleton;
  }

  public void init(Hashtable parameters) {
    chessBoardImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "covua_banco.png");
    numberBgImage = ImageUtil.getImage(Constants.NEW_IMAGE_CATEGORY, "Nen_So.png");
    
    text11 = FontManager.getFont(FontManager.FONT_SIZE_11);
    text8 = FontManager.getFont(FontManager.FONT_SIZE_8);
    moneyChangeMessage = "";
    moneyChangeIndex = -1;

    setTimerListener(this);
    
    TwoDimensionInt CHAT_LOCATION_240x320 = new TwoDimensionInt(2, 2);
    CHAT_LOCATION_240x320.setRow(0, new IntArray(new int[] {6, 254}, 2));
    CHAT_LOCATION_240x320.setRow(1, new IntArray(new int[] {6, 8}, 2));
    
    TwoDimensionInt CHAT_LOCATION_320x240 = new TwoDimensionInt(2, 2);
    CHAT_LOCATION_320x240.setRow(0, new IntArray(new int[] {220, 185}, 2));
    CHAT_LOCATION_320x240.setRow(1, new IntArray(new int[] {220, 51}, 2));
    
    Global.initChatComponent(CHAT_LOCATION_240x320, CHAT_LOCATION_320x240);
    _manager.enableTouchPad();
  }

  public void onRecieveData(DataPackage dataPackage) {
    int header = dataPackage.getHeader();
    switch (header) {
    case MOVE_NOTIFY_RESPONSE:
      int side = dataPackage.nextInt();
      int chessManIndex1 = dataPackage.nextInt();
      int column = dataPackage.nextInt();
      int row = dataPackage.nextInt();

      int otherSide = BroadChessMan.RED_SIDE;
      if (side == BroadChessMan.RED_SIDE) {
        otherSide = BroadChessMan.BLACK_SIDE;
      }

      if (mySide == BroadChessMan.BLACK_SIDE) {
        chessManIndex1 = getInverseIndex(chessManIndex1);
        column = NUMBER_OF_COLUMN - column - 1;
        row = NUMBER_OF_ROW - row - 1;
      }

      BroadChessMan chessMan = chessMans[side][chessManIndex1];
      if (side == opponentSide) {
        lastMoveSmallSprite.changePosition(chessMan.getColumn(), chessMan.getRow());
        lastMoveSmallSprite.setVisible(true);
      }

      chessMan.changePosition(column, row);
      BroadChessMan myChessMan = getChessMan(otherSide, column, row);
      if (myChessMan != null) {
        killChessMan(myChessMan);
      }

      if (side == opponentSide) {
        lastMoveLargeSprite.changePosition(column, row);
        lastMoveLargeSprite.setVisible(true);
      }
      changeTurn();
      break;
    case WIN_GAME_NOTIFY_RESPONSE:
      winSide = dataPackage.nextInt();
      winReason = dataPackage.nextInt();
      moneyChangePoint[0] = String.valueOf(dataPackage.nextInt());
      moneyChangePoint[1] = String.valueOf(dataPackage.nextInt());
      
      if (winSide == mySide) {
        moneyChangeMessage = "Thưởng " + moneyChangePoint[0] + " gold";
      } else {
        moneyChangeMessage = "Trừ " + Math.abs(NumberUtil.parseInt(moneyChangePoint[0])) + " gold";
      }
      moneyChangeIndex = 0;
      
      if (Global.systemCanvas.frmCurrent != FrmBroadChess.instance()) {
        return;
      }

      // Kiểm tra xem là thắng cuộc trong trường hợp nào
      if (winReason == NORMAL_WIN_REASON) {
        currentGameStatus = SHOW_WIN_OR_LOST_ALERT_STATUS;
      } else if (winReason == OPPONENT_RESIGN_WIN_REASON) {
        GameGlobal.alert.showAlert1(this, GameAlert.OK_TYPE, StringArray.create1("Đối thủ đã bỏ cuộc", "Bạn đã thắng"), 97);
      } else if (winReason == OPPONENT_TIMEOUT_WIN_REASON) {
        if (winSide == mySide) {
          GameGlobal.alert.showAlert1(this, GameAlert.OK_TYPE, StringArray.create1("Đối thủ đã hết thời gian", "Bạn đã thắng"), 97);
        } else {
          GameGlobal.alert.showAlert1(this, GameAlert.OK_TYPE, StringArray.create1("Thời gian cho nước đi đã hết", "Bạn đã thua"), 97);
        }
      }
      break;
    case MOVE_ERROR_RESPONSE:
      int error = dataPackage.nextInt();
      if (error == NOT_YOUR_TURN_ERROR) {
        GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Không phải lượt đánh của bạn");
      } else if (error == MOVE_IN_NOT_ALLOW_POSITION) {
      } else {
        GameGlobal.alert.showAlert(this, GameAlert.OK_TYPE, "Nước đi không được phép");
      }
      break;
    case INIT_DATA_RESPONSE:
      initForGame(dataPackage);
      break;
    }
  }

  private void initForGame(DataPackage dataPackage) {
    // Init time
    int timePerMatch = dataPackage.nextInt();
    TIME_PER_MOVE = dataPackage.nextInt();
    timeMove = TIME_PER_MOVE;
    timePlay = new int[2];
    timePlay[0] = timePerMatch;
    timePlay[1] = timePerMatch;

    // Init side
    String redSideName = dataPackage.nextString();
    if (redSideName.equals(Global.currentUser.getName())) {
      mySide = BroadChessMan.RED_SIDE;
      opponentSide = BroadChessMan.BLACK_SIDE;
      oponentName = dataPackage.nextString();
    } else {
      mySide = BroadChessMan.BLACK_SIDE;
      opponentSide = BroadChessMan.RED_SIDE;
      oponentName = redSideName;
    }
    currentTurn = BroadChessMan.RED_SIDE;

    initChessBoard();
    currentGameStatus = PLAY_STATUS;
  }

  private void initChessBoard() {
    if (GameConstants.IS_240x320_SCREEN) {
      CELL_SIZE = 27;
      BOARD_DX = 12;
      BOARD_DY = 43;
    } else {
      CELL_SIZE = 27;
      BOARD_DX = 60;
      BOARD_DY = 5;
    }

    chessMans = new BroadChessMan[2][16];
    chessMans[BroadChessMan.RED_SIDE] = new BroadChessMan[16];
    chessMans[BroadChessMan.BLACK_SIDE] = new BroadChessMan[16];

    int[][] downSide = new int[][]{{0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}, {7, 6}, {0, 7}, {7, 7}, {1, 7}, {6, 7}, {2, 7}, {5, 7}, {3, 7}, {4, 7}};
    int[][] upSide = new int[][]{{0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {0, 0}, {7, 0}, {1, 0}, {6, 0}, {2, 0}, {5, 0}, {3, 0}, {4, 0}};
    int[][] redSide = null;
    int[][] blackSide = null;
    if (mySide == BroadChessMan.RED_SIDE) {
      redSide = downSide;
      blackSide = upSide;

    } else {
      redSide = upSide;
      blackSide = downSide;
    }

    areaImage = ImageUtil.getImage(Constants.NEW_IMAGE_CATEGORY, "area.png");
    currentSelectArea = new BroadChessMan(BroadChessMan.NO_SIDE, BroadChessMan.CHOOSE_AREA_TYPE, areaImage, 4, 7);
    currentSelectArea1 = new BroadChessMan(BroadChessMan.NO_SIDE, BroadChessMan.CHOOSE_AREA_TYPE, areaImage, 4, 7);
    currentSelectArea1.setVisible(false);

    GameImage tmpImage = null;
    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua00.png");
    for (int i = 0; i < 8; i++) {
      chessMans[BroadChessMan.RED_SIDE][i] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.TOT_TYPE, tmpImage, redSide[i][0], redSide[i][1]);
    }
    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua10.png");
    for (int i = 0; i < 8; i++) {
      chessMans[BroadChessMan.BLACK_SIDE][i] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.TOT_TYPE, tmpImage, blackSide[i][0], blackSide[i][1]);
    }
    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua03.png");
    chessMans[BroadChessMan.RED_SIDE][8] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.XE_TYPE, tmpImage, redSide[8][0], redSide[8][1]);
    chessMans[BroadChessMan.RED_SIDE][9] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.XE_TYPE, tmpImage, redSide[9][0], redSide[9][1]);

    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua01.png");
    chessMans[BroadChessMan.RED_SIDE][10] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.MA_TYPE, tmpImage, redSide[10][0], redSide[10][1]);
    chessMans[BroadChessMan.RED_SIDE][11] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.MA_TYPE, tmpImage, redSide[11][0], redSide[11][1]);

    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua02.png");
    chessMans[BroadChessMan.RED_SIDE][12] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.TUONG_TYPE, tmpImage, redSide[12][0], redSide[12][1]);
    chessMans[BroadChessMan.RED_SIDE][13] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.TUONG_TYPE, tmpImage, redSide[13][0], redSide[13][1]);
    if (mySide == BroadChessMan.RED_SIDE) {
      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua04.png");
      chessMans[BroadChessMan.RED_SIDE][14] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.VUA_TYPE, tmpImage, redSide[14][0], redSide[14][1]);

      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua05.png");
      chessMans[BroadChessMan.RED_SIDE][15] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.HAU_TYPE, tmpImage, redSide[15][0], redSide[15][1]);
    } else {
      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua04.png");
      chessMans[BroadChessMan.RED_SIDE][14] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.VUA_TYPE, tmpImage, redSide[15][0], redSide[15][1]);

      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua05.png");
      chessMans[BroadChessMan.RED_SIDE][15] = new BroadChessMan(BroadChessMan.RED_SIDE, BroadChessMan.HAU_TYPE, tmpImage, redSide[14][0], redSide[14][1]);
    }

    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua13.png");
    chessMans[BroadChessMan.BLACK_SIDE][8] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.XE_TYPE, tmpImage, blackSide[8][0], blackSide[8][1]);
    chessMans[BroadChessMan.BLACK_SIDE][9] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.XE_TYPE, tmpImage, blackSide[9][0], blackSide[9][1]);

    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua11.png");
    chessMans[BroadChessMan.BLACK_SIDE][10] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.MA_TYPE, tmpImage, blackSide[10][0], blackSide[10][1]);
    chessMans[BroadChessMan.BLACK_SIDE][11] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.MA_TYPE, tmpImage, blackSide[11][0], blackSide[11][1]);

    tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua12.png");
    chessMans[BroadChessMan.BLACK_SIDE][12] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.TUONG_TYPE, tmpImage, blackSide[12][0], blackSide[12][1]);
    chessMans[BroadChessMan.BLACK_SIDE][13] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.TUONG_TYPE, tmpImage, blackSide[13][0], blackSide[13][1]);
    if (mySide == BroadChessMan.RED_SIDE) {
      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua14.png");
      chessMans[BroadChessMan.BLACK_SIDE][14] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.VUA_TYPE, tmpImage, blackSide[14][0], blackSide[14][1]);

      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua15.png");
      chessMans[BroadChessMan.BLACK_SIDE][15] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.HAU_TYPE, tmpImage, blackSide[15][0], blackSide[15][1]);
    } else {
      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua14.png");
      chessMans[BroadChessMan.BLACK_SIDE][14] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.VUA_TYPE, tmpImage, blackSide[15][0], blackSide[15][1]);

      tmpImage = ImageUtil.getImage(Constants.CO_VUA_IMAGE_CATEGORY, "CoVua15.png");
      chessMans[BroadChessMan.BLACK_SIDE][15] = new BroadChessMan(BroadChessMan.BLACK_SIDE, BroadChessMan.HAU_TYPE, tmpImage, blackSide[14][0], blackSide[14][1]);
    }

    // ảnh vẽ hiệu ứng
    starImage = ImageUtil.getImage(Constants.HIEU_UNG_IMAGE_CATEGORY, "HieuUng.png");
    matnaImage = ImageUtil.joinAndCreateImages(ImageUtil.getImage(Constants.HIEU_UNG_IMAGE_CATEGORY, "pxiel_nen.png"), GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT - 20);
    thuaImage = ImageUtil.getImage(Constants.HIEU_UNG_IMAGE_CATEGORY, "icon_lose.png");
    thangImage = ImageUtil.getImage(Constants.HIEU_UNG_IMAGE_CATEGORY, "icon_win.png");

    lastMoveSmallImage = ImageUtil.getImage(Constants.NEW_IMAGE_CATEGORY, "move_small.png");
    lastMoveLargeImage = ImageUtil.getImage(Constants.NEW_IMAGE_CATEGORY, "move_large.png");

    lastMoveSmallSprite = new BroadChessMan(BroadChessMan.NO_SIDE, BroadChessMan.CHOOSE_AREA_TYPE, lastMoveSmallImage, 4, 7);
    lastMoveSmallSprite.setVisible(false);
    lastMoveLargeSprite = new BroadChessMan(BroadChessMan.NO_SIDE, BroadChessMan.CHOOSE_AREA_TYPE, lastMoveLargeImage, 4, 7);
    lastMoveLargeSprite.setVisible(false);
  }
  
  private void drawMoneyChangeNotification(Graphics g) {
    if (moneyChangeIndex > 0) {
      g.setColor(0xFFA500);
      g.fillRoundRect(GameConstants.SCREEN_WIDTH / 2 - 80, GameConstants.SCREEN_HEIGHT / 2 - 22, 160, 24, 5, 5);
      text8.drawString2(g, moneyChangeMessage, GameColor.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 - 20, GameConstants.TOP_HCENTER_ANCHOR);
    }
  }

  public void draw(Graphics g) {
    DrawUtils.drawBackground(g);
    
    // Draw user info
    drawUserInfo(g);
    
    // Draw chess board
    g.drawImage(chessBoardImage, BOARD_DX - 1, BOARD_DY, GameConstants.TOP_LEFT_ANCHOR);

    // Draw chess man
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 16; j++) {
        BroadChessMan chessMan = chessMans[i][j];
        if ((chessMan != null) && chessMan.isVisible()) {
          g.drawImage(chessMan.getImage(), BOARD_DX + chessMan.getColumn() * CELL_SIZE, BOARD_DY + chessMan.getRow() * (CELL_SIZE - 1), Constants.TOP_LEFT_ANCHOR);
        }
      }
    }

    // Draw last move lastMoveSmallSprite and lastMoveLargeSprite
    if ((lastMoveSmallSprite != null) && lastMoveSmallSprite.isVisible()) {
      g.drawImage(lastMoveSmallSprite.getImage(), BOARD_DX + lastMoveSmallSprite.getColumn() * CELL_SIZE, BOARD_DY + lastMoveSmallSprite.getRow() * (CELL_SIZE - 1), Constants.TOP_LEFT_ANCHOR);
    }
    if ((lastMoveLargeSprite != null) && lastMoveLargeSprite.isVisible()) {
      g.drawImage(lastMoveLargeSprite.getImage(), BOARD_DX + lastMoveLargeSprite.getColumn() * CELL_SIZE, BOARD_DY + lastMoveLargeSprite.getRow() * (CELL_SIZE - 1), Constants.TOP_LEFT_ANCHOR);
    }
    if ((currentSelectArea != null) && currentSelectArea.isVisible()) {
      g.drawImage(currentSelectArea.getImage(), BOARD_DX + currentSelectArea.getColumn() * CELL_SIZE, BOARD_DY + currentSelectArea.getRow() * (CELL_SIZE - 1), Constants.TOP_LEFT_ANCHOR);
    }
    if ((currentSelectArea1 != null) && currentSelectArea1.isVisible()) {
      g.drawImage(currentSelectArea1.getImage(), BOARD_DX + currentSelectArea1.getColumn() * CELL_SIZE, BOARD_DY + currentSelectArea1.getRow() * (CELL_SIZE - 1), Constants.TOP_LEFT_ANCHOR);
    }

    // Draw command bar
    if ((currentGameStatus == SHOW_FINAL_RESULL) || (currentGameStatus == SHOW_WIN_OR_LOST_ALERT_STATUS)) {
      DrawUtils.setBottomBar(_manager, "", "Chơi tiếp", "Thoát");
    } else {
      DrawUtils.setBottomBar(_manager, "", "", "Thoát");
    }
    Global.drawChat(g);

    // draw hiệu ứng cuối ván
    switch (currentGameStatus) {
    case SHOW_WIN_OR_LOST_ALERT_STATUS:
      g.drawImage(matnaImage, 0, 0, GameConstants.TOP_LEFT_ANCHOR);
      g.drawImage(starImage, GameConstants.SCREEN_WIDTH / 2, (GameConstants.SCREEN_HEIGHT - 20) / 2, GameConstants.CENTER_ANCHOR);

      if (winSide == mySide) {
        g.drawImage(thangImage, GameConstants.SCREEN_WIDTH / 2, (GameConstants.SCREEN_HEIGHT - 20) / 2, GameConstants.CENTER_ANCHOR);
      } else {
        g.drawImage(thuaImage, GameConstants.SCREEN_WIDTH / 2, (GameConstants.SCREEN_HEIGHT - 20) / 2, GameConstants.CENTER_ANCHOR);
      }
      break;
    case SHOW_FINAL_RESULL:
      drawMoneyChangeNotification(g);
      break;
    }
  }
  
  private void drawUserInfo(Graphics g) {
    if (GameConstants.IS_240x320_SCREEN) {
      // Draw oponent
      DrawUtils.drawUserInfo(g, oponentName, 0, 0, false);
      
      // Draw remain time of oponent
      int tmp0 = timePlay[0] % 60;
      int tmp1 = timePlay[1] % 60;
      if (mySide == ChessMan.RED_SIDE) {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[1] / 60, 2) + ":" + fillUpStringNumberToLen(tmp1, 2), GameColor.WHITE_CODE, 178, 4, GameConstants.TOP_LEFT_ANCHOR);
      } else {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[0] / 60, 2) + ":" + fillUpStringNumberToLen(tmp0, 2), GameColor.WHITE_CODE, 178, 4, GameConstants.TOP_LEFT_ANCHOR);
      }
      
      // Draw user
      DrawUtils.drawUserInfo(g, Global.currentUser.getName(), 5, 240, false);
      
      // Draw remain time of user
      tmp0 = timePlay[0] % 60;
      tmp1 = timePlay[1] % 60;
      if (mySide == ChessMan.RED_SIDE) {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[0] / 60, 2) + ":" + fillUpStringNumberToLen(tmp0, 2), GameColor.WHITE_CODE, 178, 274, GameConstants.TOP_LEFT_ANCHOR);
      } else {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[1] / 60, 2) + ":" + fillUpStringNumberToLen(tmp1, 2), GameColor.WHITE_CODE, 178, 274, GameConstants.TOP_LEFT_ANCHOR);
      }
      
      // Draw count time of user
      if (currentTurn == mySide) {
        g.drawImage(numberBgImage, 55, 260, GameConstants.CENTER_ANCHOR);
        text8.drawString2(g, String.valueOf(timeMove), GameColor.WHITE_CODE, 55, 260, GameConstants.CENTER_ANCHOR);
      }
    } else {// 320x240
      // Draw oponent
      DrawUtils.drawUserInfo(g, oponentName, 5, 5, false);

      // Draw remain time of oponent
      int tmp0 = timePlay[0] % 60;
      int tmp1 = timePlay[1] % 60;
      if (mySide == ChessMan.RED_SIDE) {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[1] / 60, 2) + ":" + fillUpStringNumberToLen(tmp1, 2), GameColor.WHITE_CODE, 316, 16, GameConstants.TOP_RIGHT_ANCHOR);
      } else {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[0] / 60, 2) + ":" + fillUpStringNumberToLen(tmp0, 2), GameColor.WHITE_CODE, 316, 16, GameConstants.TOP_RIGHT_ANCHOR);
      }

      // Draw user
      DrawUtils.drawUserInfo(g, Global.currentUser.getName(), 5, 150, false);
      
      // Draw remain time of user
      if (mySide == ChessMan.RED_SIDE) {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[0] / 60, 2) + ":" + fillUpStringNumberToLen(tmp0, 2), GameColor.WHITE_CODE, 316, 185, GameConstants.TOP_RIGHT_ANCHOR);
      } else {
        text11.drawString2(g, fillUpStringNumberToLen(timePlay[1] / 60, 2) + ":" + fillUpStringNumberToLen(tmp1, 2), GameColor.WHITE_CODE, 316, 185, GameConstants.TOP_RIGHT_ANCHOR);
      }
      
      // Draw count time for user
      if (currentTurn == mySide) {
        g.drawImage(numberBgImage, 10, 145, GameConstants.CENTER_ANCHOR);
        text8.drawString2(g, String.valueOf(timeMove), GameColor.WHITE_CODE, 10, 145, GameConstants.CENTER_ANCHOR);
      }
    }
  }

  public void keyReleased(int keyCode) {
    if (currentGameStatus == WAIT_FOR_INIT_STATUS) {
      return;
    }
    if (currentGameStatus == SHOW_WIN_OR_LOST_ALERT_STATUS) {
      if (keyCode == Key.FIRE) {
        currentGameStatus = SHOW_FINAL_RESULL;
      } else if (keyCode == Key.SOFT_RIGHT) {
        GameGlobal.nextState(FrmGroupTableFreeUserFriend.instance(), null);
      }
      return;
    }

    if (currentGameStatus == SHOW_FINAL_RESULL) {
      if ((keyCode == Key.FIRE) || (keyCode == Key.SOFT_RIGHT)) {
        GameGlobal.nextState(FrmGroupTableFreeUserFriend.instance(), null);
      }
      return;
    }
    
    if (!Key.isCommandKey) {
      if (Global.chatComponent != null) {
        Global.chatComponent.setShowInputChatMessageTextField(true);
        Global.chatComponent.keyReleased(keyCode);
      }
      return;
    }

    switch (keyCode) {
    case Key.LEFT:
    case Key.K_4:
      if (currentSelectArea.getColumn() > 0) {
        currentSelectArea.move(-1, 0);
      }
      break;
    case Key.RIGHT:
    case Key.K_6:
      if (currentSelectArea.getColumn() < 7) {
        currentSelectArea.move(1, 0);
      }
      break;
    case Key.UP:
    case Key.K_2:
      if (currentSelectArea.getRow() > 0) {
        currentSelectArea.move(0, -1);
      }
      break;
    case Key.DOWN:
    case Key.K_8:
      if (currentSelectArea.getRow() < 7) {
        currentSelectArea.move(0, 1);
      }
      break;
    case Key.SOFT_LEFT:
      Global.hideInputChatBox();
      break;
    case Key.SOFT_RIGHT:
      if (Global.isShowedInputChatBox()) {
        Global.chatComponent.getChatTextField().deleteLastChar();
      } else {
        if ((currentGameStatus != SHOW_FINAL_RESULL) && (currentGameStatus != SHOW_WIN_OR_LOST_ALERT_STATUS)) {
          GameGlobal.alert.showAlert1(this, GameAlert.YES_NO_TYPE, StringArray.create1("Thoát ra bị tính là thua cuộc", "Bạn có muốn thoát ra?"), 98);
        }
      }
      break;
    case Key.FIRE:
    case Key.K_5:
      if (Global.isShowedInputChatBox()) {
        SocketClientUtil.sendMessage(Global.chatComponent.getCurrentRoomId(), Global.chatComponent.getChatTextField().getText());
        Global.hideInputChatBox();
        return;
      }
      
      BroadChessMan selectedChessMan1 = getChessMan(mySide, currentSelectArea.getColumn(), currentSelectArea.getRow());
      if (selectedChessMan1 != null) {
        // Nếu chọn quân cờ phe mình và đang nước đi của mình
        if ((selectedChessMan1.getSide() == mySide) && (currentTurn == mySide)) {
          currentSelectArea1.changePosition(currentSelectArea.getColumn(), currentSelectArea.getRow());
          currentSelectArea1.setVisible(true);
          this.selectedChessMan = selectedChessMan1;
        }
      } else {
        // Nếu chọn nước đi
        if (currentSelectArea1.isVisible()) {
          chessManIndex = getIndexOfChessMan(this.selectedChessMan);
          if (currentTurn == BroadChessMan.RED_SIDE) {
            sendMoveAction(chessManIndex, currentSelectArea.getColumn(), currentSelectArea.getRow());
          } else {
            sendMoveAction(getInverseIndex(chessManIndex), NUMBER_OF_COLUMN - currentSelectArea.getColumn() - 1, NUMBER_OF_ROW - currentSelectArea.getRow() - 1);
          }
        }
      }
      break;
    }
  }

  private void sendMoveAction(int chessManIndex1, int column, int row) {
    DataPackage movePackage = Game.createGamePackage(MOVE_REQUEST);
    movePackage.putInt(chessManIndex1);
    movePackage.putInt(column);
    movePackage.putInt(row);
    Global.gameActionClient.write(movePackage);
  }

  public void alertEventPerform(int alertType, int eventType, int alertId) {
    if (alertId == 98) { // Sự kiện thoát ra giữa ván
      if (eventType == GameAlert.YES_BUTTON) {
        SocketClientUtil.leaveTableRequest();
        GameGlobal.nextState(FrmGroupListTableFreeUserChat.instance(), null);
      }
      return;
    } else if (alertId == 97) { // Sự kiện báo đối phương đã thoát hoặc time out
      currentGameStatus = SHOW_FINAL_RESULL;
    }
  }

  private String fillUpStringNumberToLen(int input, int len) {
    String str = String.valueOf(input);
    int lackLen = len - str.length();
    if (lackLen > 0) {
      for (int i = 0; i < lackLen; i++) {
        str = "0" + str;
      }
    }
    return str;
  }

  private void changeTurn() {
    if (currentTurn == BroadChessMan.BLACK_SIDE) {
      currentTurn = BroadChessMan.RED_SIDE;
    } else {
      currentTurn = BroadChessMan.BLACK_SIDE;
    }
    selectedChessMan = null;
    currentSelectArea1.setVisible(false);
    timeMove = TIME_PER_MOVE;
  }

  private int getIndexOfChessMan(BroadChessMan chessMan) {
    if (chessMan == null) {
      System.out.println("getIndexOfChessMan : chessMan is null");
      return -1;
    }
    for (int i = 0; i < 16; i++) {
      if (chessMans[chessMan.getSide()][i] == chessMan) {
        return i;
      }
    }
    return -1;
  }

  private BroadChessMan getChessMan(int side, int column, int row) {
    if ((column < 0) || (column > NUMBER_OF_COLUMN - 1) || (row < 0) || (row > NUMBER_OF_ROW - 1)) {
      return null;
    }

    for (int i = 0; i < 16; i++) {
      if (chessMans[side][i] != null) {
        if ((chessMans[side][i].getColumn() == column) && (chessMans[side][i].getRow() == row)) {
          return chessMans[side][i];
        }
      }
    }
    return null;
  }

  private void killChessMan(BroadChessMan chessMan) {
    if (chessMan == null) {
      return;
    }

    for (int i = 0; i < 16; i++) {
      if (chessMans[chessMan.getSide()][i] == chessMan) {
        chessMans[chessMan.getSide()][i] = null;
        chessMan.setVisible(false);
        return;
      }
    }
  }

  public void doTask() {
    count = (count + 1) % 1200;
    if (count % 10 == 0) {
      if ((currentGameStatus != SHOW_FINAL_RESULL) && (currentGameStatus != SHOW_WIN_OR_LOST_ALERT_STATUS)) {
        if (count % 10 == 0) {
          if (timeMove > 0) {
            timeMove--;
          }

          if (currentTurn == BroadChessMan.RED_SIDE) {
            if (timePlay[0] > 0) {
              timePlay[0]--;
            }
          } else {
            if (timePlay[1] > 0) {
              timePlay[1]--;
            }
          }
        }
      }
    }
    
    if (moneyChangeIndex > -1) {
      moneyChangeIndex++;
      if (moneyChangeIndex > 50) {
        moneyChangeIndex = -1;
      }
    }
  }

  public int getInverseIndex(int index) {
    int tmp = 0;
    switch (index) {
    case 0:
      tmp = 7;
      break;
    case 1:
      tmp = 6;
      break;
    case 2:
      tmp = 5;
      break;
    case 3:
      tmp = 4;
      break;
    case 4:
      tmp = 3;
      break;
    case 5:
      tmp = 2;
      break;
    case 6:
      tmp = 1;
      break;
    case 7:
      tmp = 0;
      break;
    case 8:
      tmp = 9;
      break;
    case 9:
      tmp = 8;
      break;
    case 10:
      tmp = 11;
      break;
    case 11:
      tmp = 10;
      break;
    case 12:
      tmp = 13;
      break;
    case 13:
      tmp = 12;
      break;
    case 14:
      tmp = 14;
      break;
    case 15:
      tmp = 15;
      break;
    default:
      break;
    }
    return tmp;
  }

  public void destroy() {
    chessBoardImage = null;
    numberBgImage = null;
    currentGameStatus = WAIT_FOR_INIT_STATUS;
    areaImage = null;
    lastMoveSmallImage = null;
    lastMoveLargeImage = null;
    chessMans = null;
    currentSelectArea = null;
    currentSelectArea1 = null;
    selectedChessMan = null;
    lastMoveSmallSprite = null;
    lastMoveLargeSprite = null;
    matnaImage = null;
    starImage = null;
    thangImage = null;
    thuaImage = null;
    text11 = null;
    text8 = null;
    oponentName = null;
  }

  public void onConnectDone() {
  }

  public void onConnectFail() {
  }

  public void onDisconnect() {
  }
}
